<template>
    <div ref="threejsContainer" class="threejs-container"></div>
    <!-- <div style="position: fixed;top:-10px;left: -10px;width: 120%; height: 100px;background-color:cornflowerblue;">
      <img src="left-image.jpg" alt="Left Image" class="left-image">
      <img src="right-image.jpg" alt="Right Image" class="right-image">
    </div> -->
    <div class="image-container">
      <img src="title.png" alt="Left Image" class="left-image">
      <img src="logo.png" alt="Right Image" class="right-image">
    </div>
    
    <div class="info-panel" v-if="switch_status.showInfoPanel">
      <h3>比亚迪秦混动系统简介</h3>
      <p>比亚迪秦搭载的DM-i超级混动系统，通过一台超高效率的专用发动机、高度集成的双电机电混系统（EHS）以及大容量刀片电池，实现了以电驱为主、发动机高效发电或辅助直驱的工作方式。</p>
      <h3>混动系统的设计目标</h3>
      <p>（1）DM-i的首要目标是将油耗降到最低，尤其是亏电状态下的油耗，使其接近甚至低于同级传统燃油车。官方NEDC亏电油耗可低至3.8L/100km（具体因车型配置和测试工况略有差异）。</p>
      <p>（2）通过让发动机尽可能工作在高效区间发电，由电机驱动车辆，避免发动机在低效区间工作。</p>
      <h3>核心组件</h3>
      <p>（1） 骁云-插混专用1.5L高效发动机： 这是一款专为混动设计的阿特金森循环发动机，追求超高热效率（最高可达43.04%）。它取消了传统轮系（如空调压缩机、机械水泵等），采用电气化附件，结构更简化，主要功能是在高效区间发电，只有在高速巡航等特定工况下才直接驱动车辆。</p>
      <p>（2）EHS电混系统： 这是系统的核心中枢，高度集成了：</p>

      <p>·双电机： 一个驱动电机（负责主要驱动车辆）和一个发电机（负责发电，也可在特定工况辅助驱动）。</p>

      <p>·电控系统： 智能控制动力分配、模式切换。</p>

      <p>·单挡减速器/离合器： 结构相对简单，取消了传统变速箱（如DCT），主要依靠电机调速，实现无级变速般的平顺性。在需要发动机直驱时，通过离合器结合。</p>
      <p>（3）DM-i超级混动专用功率型刀片电池： 提供纯电续航里程（NEDC标准下通常有55km或120km两种版本可选）。刀片电池以其高安全性（通过针刺试验）、高体积利用率和长寿命著称。</p>
      <p>（4）交直流车载充电器： 支持外部充电。</p>

      <h3>工作原理与驱动模式</h3>
      <p>（1）EV纯电模式： 电池电量充足时，车辆完全由驱动电机驱动，发动机不启动，相当于一台纯电动车。安静、零油耗、零排放</p>
      <p>（2）HEV串联模式（增程模式）： 当电池电量较低或需要更强动力时，发动机启动，但不直接驱动车轮，而是在高效区间带动发电机发电。发出的电优先供给驱动电机驱动车辆，多余的电量则给电池充电。这是市区中低速行驶的主要模式。</p>
      <p>（3）HEV并联模式： 在需要急加速或高速巡航时，系统判断发动机处于高效直驱区间。此时，离合器结合，发动机直接驱动车轮，同时驱动电机也可以根据需求提供辅助动力（并联驱动），实现最强动力输出。</p>
      <p>（4）发动机直驱模式： 主要在高速稳定巡航时使用。此时发动机高效地直接驱动车轮，驱动电机和发电机根据情况可能不工作或辅助调节。</p>
      <p>（5）能量回收模式： 车辆减速或制动时，驱动电机转化为发电机，将动能回收为电能存储到电池中。</p>

      <h3>主要优势</h3>
      <p>（1）超低油耗： 亏电油耗远低于传统燃油车，日常使用成本极低。</p>
      <p>（2）平顺静谧： 电驱为主，无传统变速箱换挡顿挫，行驶质感接近纯电动车，尤其在城市路况下非常安静平顺。</p>
      <p>（3）强劲动力： 电机提供瞬间大扭矩，0-100km/h加速通常在7秒级（秦PLUS DM-i 120KM版本），动力响应快。</p>
      <p>（4）长续航： 满油满电综合续航里程轻松超过1000公里，彻底消除里程焦虑。</p>
      

      

    </div>
    <!-- <div  v-if="showInfoPanel" style="z-index: 11; position: fixed;bottom: 30px;left: 180px;">
      <button :class="['switch_button3', !showInfoPanel ? 'switch_on' : 'switch_off']" @click="switchInfoShow">{{ showInfoPanel ? "隐藏简介" : "显示简介" }}</button>
    </div>

    <div v-if="!showInfoPanel" ref="info" class="info">
       <button :class="['switch_button3', !showInfoPanel ? 'switch_on' : 'switch_off']" @click="switchInfoShow">{{ showInfoPanel ? "隐藏简介" : "显示简介" }}</button>
    </div> -->

    <!-- 控制面板 -->
    <div class="control-panel">
      <button :class="['switch_button', !switch_status.showInfoPanel ? 'switch_on' : 'switch_off']" @click="updateSwitch($event,'showInfoPanel')">{{ switch_status.showInfoPanel ? "简介已显示" : "简介已隐藏" }}</button>
      <button :class="['switch_button', !switch_status.motor ? 'switch_on' : 'switch_off']" id = "motor" @click="updateSwitch($event,'motor')">{{ switch_status.motor ? "电机已开" : "电机已关"  }}</button>
      <button :class="['switch_button', !switch_status.headlights ? 'switch_on' : 'switch_off']" @click="updateSwitch($event,'headlights')">{{ switch_status.headlights ? "大灯已开" : "大灯已关" }}</button>
      <button :class="['switch_button', !switch_status.colorlights ? 'switch_on' : 'switch_off']" @click="updateSwitch($event,'colorlights')">{{ switch_status.colorlights ? "彩灯已开" : "彩灯已关"  }}</button>
      <!-- <button :class="['switch_button', !switch_status.power ? 'switch_on' : 'switch_off']" @click="updateSwitch($event,'power')">{{ switch_status.power ? "电源已开" : "电源已关"  }}</button> -->
    </div>
    <div ref="top_window" class="label">
      <button class="switch_button2"
        @pointerdown="updateWindow($event,'top_window','up')"
        @pointerup="updateWindow($event,'top_window','')"
        @contextmenu.prevent

      >升起天窗</button>
      <button class="switch_button2"
        @pointerdown="updateWindow($event,'top_window','down')"
        @pointerup="updateWindow($event,'top_window','')"
        @contextmenu.prevent
      >降下天窗</button>
    </div>

    <div ref="left_f_window" class="label">
      <button class="switch_button2"
        @pointerdown="updateWindow($event,'left_f_window','up')"
        @pointerup="updateWindow($event,'left_f_window','')"
        @contextmenu.prevent
      >升起左前窗</button>
      <button class="switch_button2"
        @pointerdown="updateWindow($event,'left_f_window','down')"
        @pointerup="updateWindow($event,'left_f_window','')"
        @contextmenu.prevent
      >降下左前窗</button>
    </div>

    <div ref="left_r_window" class="label">
      <button class="switch_button2"
        @pointerdown="updateWindow($event,'left_r_window','up')"
        @pointerup="updateWindow($event,'left_r_window','')"
        @contextmenu.prevent
      >升起左后窗</button>
      <button class="switch_button2"
        @pointerdown="updateWindow($event,'left_r_window','down')"
        @pointerup="updateWindow($event,'left_r_window','')"
        @contextmenu.prevent
      >降下左后窗</button>
    </div>

    <div ref="right_f_window" class="label">
      <button class="switch_button2"
        @pointerdown="updateWindow($event,'right_f_window','up')"
        @pointerup="updateWindow($event,'right_f_window','')"
        @contextmenu.prevent
      >升起右前窗</button>
      <button class="switch_button2"
        @pointerdown="updateWindow($event,'right_f_window','down')"
        @pointerup="updateWindow($event,'right_f_window','')"
        @contextmenu.prevent
      >降下右前窗</button>
    </div>

    <div ref="right_r_window" class="label">
      <button class="switch_button2"
        @pointerdown="updateWindow($event,'right_r_window','up')"
        @pointerup="updateWindow($event,'right_r_window','')"
        @contextmenu.prevent
      >升起右后窗</button>
      <button class="switch_button2"
        @pointerdown="updateWindow($event,'right_r_window','down')"
        @pointerup="updateWindow($event,'right_r_window','')"
        @contextmenu.prevent
      >降下右后窗</button>
    </div>



    <!-- <div ref="left_f_window" class="label">
      <button :class="['switch_button', !switch_status.left_f_window ? 'switch_on' : 'switch_off']" class="switch_button2" @click="updateSwitch($event,'left_f_window')">{{ switch_status.left_f_window ? "左前窗已开" : "左前窗已关" }}</button>
    </div>
    <div ref="left_r_window" class="label">
      <button :class="['switch_button', !switch_status.left_r_window ? 'switch_on' : 'switch_off']" class="switch_button2" @click="updateSwitch($event,'left_r_window')">{{ switch_status.left_r_window ? "左后窗已开" : "左后窗已关" }}</button>
    </div>
    <div ref="right_f_window" class="label">
      <button :class="['switch_button', !switch_status.right_f_window ? 'switch_on' : 'switch_off']" class="switch_button2" @click="updateSwitch($event,'right_f_window')">{{ switch_status.right_f_window ? "右前窗已开" : "右前窗已关" }}</button>
    </div>
    <div ref="right_r_window" class="label">
      <button :class="['switch_button', !switch_status.right_r_window ? 'switch_on' : 'switch_off']" class="switch_button2" @click="updateSwitch($event,'right_r_window')">{{ switch_status.right_r_window ? "右后窗已开" : "右后窗已关" }}</button>
    </div> -->
    
</template>

<script>
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
// import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader';
// import { MTLLoader } from 'three/examples/jsm/loaders/MTLLoader';
import { RoomEnvironment } from 'three/examples/jsm/environments/RoomEnvironment';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
import { useToast } from "vue-toastification";
import {RGBELoader} from 'three/examples/jsm/loaders/RGBELoader';
// const post_data_url = 'http://192.168.66.66:5000/receive_data';
const post_data_url = 'http://127.0.0.1:5000/receive_data';

let timeout1;

// 函数：通过名称查找Mesh
function findMeshByName(scene, name) {
  let foundMesh = null;
  scene.traverse((object) => {
    if (object.isMesh && object.name === name) {
      foundMesh = object;
    }
  });
  return foundMesh;
}

export default {
  name: 'ThreeJsScene',
  mounted() {
    this.initThreeJS();
    window.addEventListener('resize', this.onWindowResize);
    // window.addEventListener('mousemove', this.onMouseMove);
  },
  beforeUnmount() {
    window.removeEventListener('resize', this.onWindowResize);
    // window.removeEventListener('mousemove', this.onMouseMove);
  },
  data() {
    return {
      raycaster: new THREE.Raycaster(),
      mouse: new THREE.Vector2(),
      INTERSECTED: null,
      originalColor: null,
      infoText: '默认信息',
      switch_status:{
        top_window:false,
        left_f_window:false,
        left_r_window:false,
        right_f_window:false,
        right_r_window:false,
        // info:false,
        headlights:false,
        motor:false,
        colorlights:false,
        power:false,
        showInfoPanel:false,
      },
    };
  },
  
  methods: {
    initThreeJS() {
      const width = window.innerWidth;
      const height = window.innerHeight;

      const scene = new THREE.Scene();
      this.scene = scene;
      scene.background = new THREE.Color(0xaaaadd);

      const camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 30000);
      this.camera = camera;
      camera.position.set(0, 3.5, 3.5);

      const renderer = new THREE.WebGLRenderer({ antialias: true });
      this.renderer = renderer;
      renderer.setSize(width, height);
      this.$refs.threejsContainer.appendChild(renderer.domElement);


      const environment = new RoomEnvironment();
      const pmremGenerator = new THREE.PMREMGenerator( this.renderer );
      this.scene.environment = pmremGenerator.fromScene( environment ).texture;
      this.scene.background = new THREE.Color(0.8,0.8,0.8);


      const glbLoader = new GLTFLoader();
      glbLoader.load('BYDqinPlus.glb', function (gltf) {
          const model = gltf.scene;
          scene.add(model);
           console.log(model)
           window.hiddenPart = (index)=>{
            model.children[index].visible = false;
           }
      }, undefined, function (error) {
          console.error(error);
      });

      glbLoader.load('base.glb', function (gltf) {
          const model = gltf.scene;
          model.position.set(0,-0.15,0);
         
          scene.add(model);

         
      }, undefined, function (error) {
          console.error(error);
      });

      new RGBELoader().load( "zwartkops_straight_sunset_2k.hdr",  ( hdrEquirect ) => {
        hdrEquirect.mapping = THREE.EquirectangularReflectionMapping;
       
        this.scene.background = hdrEquirect;
      } );

      

      

      const controls = new OrbitControls(camera, renderer.domElement);
      controls.enableDamping = true;
      controls.dampingFactor = 0.25;
      controls.enableZoom = true;
      // 设置最远和最近距离
      controls.minDistance = 3; // 最近距离
      controls.maxDistance = 6; // 最远距离

      // 限制垂直旋转范围（例如：上下90度）
      controls.minPolarAngle = -Math.PI/2; // 最小垂直角度
      controls.maxPolarAngle = Math.PI/2; // 最大垂直角度

      // 限制水平旋转范围（例如：左右180度）
      // controls.minAzimuthAngle = -Math.PI / 2; // 最小水平角度
      // controls.maxAzimuthAngle = Math.PI / 2;  // 最大水平角度

      // 禁用拖放
      controls.enablePan = false;

      const material2 = new THREE.MeshBasicMaterial({ 
        color: 0x00ff00,
        transparent: true,
        opacity: 0 
      })

      let top_window = new THREE.Mesh(new THREE.BoxGeometry(0.1,0.1,0.1), material2);
      top_window.name = 'top_window';
      top_window.position.set(0,1.6,-0.1);
      scene.add(top_window);

      let left_f_window = new THREE.Mesh(new THREE.BoxGeometry(0.1,0.1,0.1), material2);
      left_f_window.name = 'left_f_window';
      left_f_window.position.set(1.8,1,0.5);
      scene.add(left_f_window);


      let left_r_window = new THREE.Mesh(new THREE.BoxGeometry(0.1,0.1,0.1), material2);
      left_r_window.name = 'left_r_window';
      left_r_window.position.set(1.8,1,-0.8);
      scene.add(left_r_window);


      let right_f_window = new THREE.Mesh(new THREE.BoxGeometry(0.1,0.1,0.1), material2);
      right_f_window.name = 'right_f_window';
      right_f_window.position.set(-1.8,1,0.5);
      scene.add(right_f_window);


      let right_r_window = new THREE.Mesh(new THREE.BoxGeometry(0.1,0.1,0.1), material2);
      right_r_window.name = 'right_r_window';
      right_r_window.position.set(-1.8,1,-0.8);
      scene.add(right_r_window);

      let info = new THREE.Mesh(new THREE.BoxGeometry(0.1,0.1,0.1), material2);
      info.name = 'info';
      info.position.set(0,0.5,1.5);
      scene.add(info);






      // const raycaster = new THREE.Raycaster();
      //   const mouse = new THREE.Vector2();
  
      //   const onMouseClick = (event) => {
      //     event.preventDefault();
      //     mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
      //     mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
  
      //     raycaster.setFromCamera(mouse, camera);
      //     // const intersects = raycaster.intersectObjects(scene.children, true);
  
      //     // if (intersects.length > 0) {
           
      //     // }
      //   };
  
      //   window.addEventListener('click', onMouseClick, false);


      const animate = () => {
        requestAnimationFrame(animate);
        controls.update();
        renderer.render(scene, camera);
        this.testP()
      };

      animate();
    },
    
    onWindowResize() {
      const width = window.innerWidth;
      const height = window.innerHeight;

      this.camera.aspect = width / height;
      this.camera.updateProjectionMatrix();
      this.renderer.setSize(width, height);
    },
    updateInfo(text) {
      this.infoText = text;
    },
    getMesh2DPosition(mesh){
      const vector = new THREE.Vector3();
      vector.setFromMatrixPosition(mesh.matrixWorld);
      vector.project(this.camera);

      const widthHalf = window.innerWidth / 2;
      const heightHalf = window.innerHeight / 2;

      const x = (vector.x * widthHalf) + widthHalf;
      const y = -(vector.y * heightHalf) + heightHalf;
      return { x, y };
    },
    testP(){
      let top_window = findMeshByName(this.scene,"top_window");
      let left_f_window = findMeshByName(this.scene,"left_f_window");
      let left_r_window = findMeshByName(this.scene,"left_r_window");
      let right_f_window = findMeshByName(this.scene,"right_f_window");
      let right_r_window = findMeshByName(this.scene,"right_r_window");
      // let info = findMeshByName(this.scene,"info");
      if(!top_window || !left_f_window || !left_r_window || !right_f_window || !right_r_window) return;
      let top_window_p = this.getMesh2DPosition(top_window);
      let left_f_window_p = this.getMesh2DPosition(left_f_window);
      let left_r_window_p = this.getMesh2DPosition(left_r_window);
      let right_f_window_p = this.getMesh2DPosition(right_f_window);
      let right_r_window_p = this.getMesh2DPosition(right_r_window);
      // let info_p = this.getMesh2DPosition(info);

      this.$refs.top_window.style.transform = `translate(-50%, -50%) translate(${top_window_p.x}px, ${top_window_p.y}px)`;
      this.$refs.left_f_window.style.transform = `translate(-50%, -50%) translate(${left_f_window_p.x}px, ${left_f_window_p.y}px)`;
      this.$refs.left_r_window.style.transform = `translate(-50%, -50%) translate(${left_r_window_p.x}px, ${left_r_window_p.y}px)`;
      this.$refs.right_f_window.style.transform = `translate(-50%, -50%) translate(${right_f_window_p.x}px, ${right_f_window_p.y}px)`;
      this.$refs.right_r_window.style.transform = `translate(-50%, -50%) translate(${right_r_window_p.x}px, ${right_r_window_p.y}px)`;
      // this.$refs.info.style.transform = `translate(-50%, -50%) translate(${info_p.x}px, ${info_p.y}px)`;
    },
    showToast(text,type) {
      const toast = useToast();
      toast(text,{
        type:type
      });
    },
    switchWindow(e){
      this.switch_status[e] = !this.switch_status[e];
    },
    switchInfoShow(){
      this.showInfoPanel = !this.showInfoPanel;
    },
    updateSwitch(e,key){
      // console.log(555)
      const button = e.target;
      button.disabled = true;
      let c2_ = button.style.backgroundColor;
      button.style.backgroundColor = 'orange'; // 设置背景颜色为浅灰色
      setTimeout(() => {
          button.disabled = false;
        button.style.backgroundColor = c2_;
      }, 1000);
      

      this.switch_status[key] = !this.switch_status[key];
      fetch(post_data_url, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(this.switch_status)
      })
    },
    updateWindow(e,key,value){
      // const button = e.target;
      // button.disabled = true;
      // console.log(button);
      // setTimeout(() => {
      //     button.disabled = false;
      // }, 1000);
      // console.log(key,value)
      clearTimeout(timeout1);
      timeout1 = setTimeout(() => {
        // console.log(key,value)
        // return
        this.switch_status[key] = value;
        fetch(post_data_url, {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json'
          },
          body: JSON.stringify(this.switch_status)
        })
      }, 250);
    }
  }
};
</script>

<style>
.image-container {
  position: fixed;
  top:-10px;
  left: -10px;
  width: 120%; 
  height: 100px;
  background-color:rgb(35, 61, 109);
}

.left-image {
  position: fixed;
  width: 750px;
  height: auto;
  left: 30px;
  top: 18px;
}

.right-image {
  position: fixed;
  width: 260px;
  height: auto;
  right: 30px;
  top: 20px;
}
.threejs-container {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
}
.info-panel {
  z-index: 10;
  position: absolute;
  top: 110px;
  left: 20px;
  background-color: rgba(0, 0, 0, 0.2);
  width: 500px;
  height: calc(100vh - 260px);
  padding: 30px;
  border-radius: 5px;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
  color: #fff;
  overflow: auto; /* 自动显示滚动条 */
  padding-bottom: 100px;
}

.control-panel {
  position: fixed;
  bottom: 10px;
  right: 10px;
  /* background-color: rgba(255, 255, 255, 0.8); */
  padding: 10px;
  /* border-radius: 5px; */
  /* box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); */
}

.label {
  position: absolute;
  /* background-color: rgba(255, 255, 255, 0.8); */
  /* width: 300px;
  height: 100px; */
  padding: 5px;
  border-radius: 3px;
  cursor: pointer;
  pointer-events: auto; /* 确保标签可以被点击 */
  display: flex; 
  justify-content: center; /* 水平居中 */
  align-items: center;    /* 垂直居中 */
  font-size: x-large;
}
button:active {
  background-color: #004080; /* 按下时的背景色 */
}
.switch_button{
  height: 120px;
  width: 120px;
  border-radius:60px;
  color: white; /* 设置字体颜色为白色 */
 
  border: none;
  margin: 10px;
  font-size:18px;
}

.switch_button2{
  height: 40px;
  width: 120px;
  border-radius:15px;
  margin: 10px;
  color: white; /* 设置字体颜色为白色 */
  background-color: #007BFF; /* 按钮背景色 */
  border: none;
  -webkit-touch-callout: none; /* 禁用 iOS 长按 */
  -webkit-user-select: none;   /* 禁用文本选择 */
  -ms-user-select: none;
  user-select: none;
}

.switch_on{
  background-color: #565656; /* 按钮背景色 */ 
  
}

.switch_off{
  background-color: #007bff; /* 按钮背景色 */
  border: #007bff;
}

.switch_button3{
  height: 50px;
  width: 200px;
  border-radius:10px;
  color: white; /* 设置字体颜色为白色 */
  border: none;
  font-size: large;
}
.info{
  position: fixed;
  top: 120px;
  left: 20px;
}
.title1{
  position: fixed;
  top: 20px;
  right: 40px;
  font-size: 32px;
  color: white; /* 设置字体颜色为白色 */

}
.title2{
  position: fixed;
  top: 70px;
  right: 40px;
  color: white; /* 设置字体颜色为白色 */
}
</style>
